package cn.backpackerxl.test;


import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

interface Rule {
    boolean evaluate(Expression expression);

    Result getRes();
}

enum Opt {
    ADD, SUB, DIV, MUL;

}

class Result {
    private final int value;

    public Result(int val) {
        this.value = val;
    }

    public int getValue() {
        return value;
    }
}

class Expression {
    private final int i;
    private final int j;
    private final Opt opt;

    public Expression(int i, int j, Opt opt) {
        this.i = i;
        this.j = j;
        this.opt = opt;
    }

    public int getI() {
        return i;
    }

    public int getJ() {
        return j;
    }

    public Opt getOpt() {
        return opt;
    }
}

class AddRule implements Rule {
    private int res;

    @Override
    public boolean evaluate(Expression expression) {
        boolean evalRes = false;
        if (expression.getOpt() == Opt.ADD) {
            this.res = expression.getI() + expression.getJ();
            evalRes = true;
        }
        return evalRes;
    }

    @Override
    public Result getRes() {
        return new Result(this.res);
    }
}

class RuleEngine {
    private static final List<Rule> rules = new ArrayList<>();

    static {
        rules.add(new AddRule());
    }

    public Result process(Expression expression) {
        Rule rule = rules.stream().filter(r -> r.evaluate(expression)).findFirst().orElseThrow(() -> new IllegalArgumentException("Expression does not matches any Rule"));
        return rule.getRes();
    }
}

public class ParseRule {
    public static void main(String[] args) {
        Expression expression = new Expression(4, 5, Opt.ADD);
        RuleEngine ru = new RuleEngine();
        Result result = ru.process(expression);
        Objects.requireNonNull(result);
        System.out.println(result.getValue());
    }
}
